package com.winit.openapi.wh.outbound.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.winit.gfs.spi.vo.GfsOrderDetail;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.spi.command.GetByKeyCommand;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.erp.spi.order.OutboundOrderInfoForWorkOrderService;
import com.winit.erp.spi.order.command.QueryOrderByTrackingNoForWorkOrderCommand;
import com.winit.erp.spi.order.vo.OutboundOrderWorkOrderHelpVo2;
import com.winit.gfs.spi.GfsOrderServices;
import com.winit.gfs.spi.vo.GfsOrder;
import com.winit.oms.spi.outbound.OutboundOrderBatchImportService;
import com.winit.oms.spi.outbound.OutboundOrderRebateService;
import com.winit.oms.spi.outbound.OutboundOrderService;
import com.winit.oms.spi.outbound.OutboundOrderTimelyAndQuantityService;
import com.winit.oms.spi.outbound.OutboundOrderTrackingService;
import com.winit.oms.spi.outbound.command.order.BatchCreateOutboundOrderCommand;
import com.winit.oms.spi.outbound.command.order.BatchQueryOutboundOrderCommand;
import com.winit.oms.spi.outbound.command.order.BatchRebateOrderCommand;
import com.winit.oms.spi.outbound.command.order.BatchValiadateOutboundOrderBuyerInfoCommand;
import com.winit.oms.spi.outbound.command.order.BatchValidateOutboundOrderCommand;
import com.winit.oms.spi.outbound.command.order.BatchVoidOutboundOrderCommand;
import com.winit.oms.spi.outbound.command.order.OutBoundOrderHistoricalPerformanceCommand;
import com.winit.oms.spi.outbound.command.order.OutBoundOrderQuantityCommand;
import com.winit.oms.spi.outbound.command.order.OutboundOrderCommand;
import com.winit.oms.spi.outbound.command.order.QueryOrderBySellerCommand;
import com.winit.oms.spi.outbound.command.order.QueryOrderByTrackingNoCommand;
import com.winit.oms.spi.outbound.command.order.QueryOrderRebateCommand;
import com.winit.oms.spi.outbound.command.order.QueryOrderTrackingCommand;
import com.winit.oms.spi.outbound.command.order.ReOrderCommand;
import com.winit.oms.spi.outbound.command.order.SubmitOutboundOrderCommand;
import com.winit.oms.spi.outbound.vo.OutboundOrderEnumContants;
import com.winit.oms.spi.outbound.vo.OutboundOrderEnumContants.OrderSource;
import com.winit.oms.spi.outbound.vo.OutboundOrderEnumContants.OrderType;
import com.winit.oms.spi.outbound.vo.OutboundOrderVo;
import com.winit.oms.spi.outbound.vo.OutboundOrderWorkOrderHelpVo;
import com.winit.oms.spi.outbound.vo.OutboundOrderWorkOrderVo;
import com.winit.oms.spi.outbound.vo.order.OutboundOrderHistoricalPerformanceVo;
import com.winit.oms.spi.outbound.vo.order.OutboundOrderPerformanceReponseVo;
import com.winit.oms.spi.outbound.vo.order.OutboundOrderQuantityVo;
import com.winit.oms.spi.outbound.vo.order.OutboundOrderRebateVo;
import com.winit.oms.spi.outbound.vo.order.OutboundOrderTrackingVo;
import com.winit.oms.spi.vo.v2.order.OrderTracking;
import com.winit.oms.spi.vo.v2.response.ErrorResult;
import com.winit.oms.spi.vo.v2.response.OrderSubmitResultVo;
import com.winit.oms.spi.vo.v2.response.OrderValidateResponse;
import com.winit.oms.spi.vo.v2.response.Response;
import com.winit.oms.spi.vo.v2.response.VoidResponse;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.EnumConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.ValidateUtil;
import com.winit.openapi.wh.outbound.builder.OutboundOrderBuilder;
import com.winit.openapi.wh.outbound.validator.OutboundOrderfieldValidator;
import com.winit.pms.spi.v2.common.PmsConstants;
import com.winit.ups.spi.command.QueryAutoTaketimeCommand;
import com.winit.ups.spi.warehouse.WarehouseService;

/**
 * 海外仓出库单
 * 
 * @version <pre>
 * Author     Version       Date        Changes
 * hui.gao    1.0         2016年5月17日     Created
 * 
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping(value = "/wh/outbound")
public class OutboundOrderController extends BaseController {

    private static final Logger                   logger = LoggerFactory.getLogger(OutboundOrderController.class);

    @Resource
    private OutboundOrderService                  outboundOrderService;
    @Resource
    private OutboundOrderRebateService            outboundOrderRebateService;
    @Resource
    private OutboundOrderInfoForWorkOrderService  outboundOrderInfoForWorkOrderService;
    @Resource
    private WarehouseService                      upsWarehouseService;
    @Resource
    private GfsOrderServices                      gfsOrderServices;
    @Resource
    private OutboundOrderTimelyAndQuantityService outboundOrderTimelyAndQuantityService;
    @Resource
    private OutboundOrderTrackingService          outboundOrderTrackingService;
    @Resource
    private OutboundOrderBatchImportService       outboundOrderBatchImportService;
    

    /**
     * 出库单列表查询.
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getOrderList")
    public String getOrderList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryOrderBySellerCommand command = new QueryOrderBySellerCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validQueryByMainOrderParam(json);
            command = OutboundOrderBuilder.buildOutboundCommand(json);
            Searchable<?> searchable = buildSearchablePageParams(json);
            if (OutboundOrderEnumContants.OrderStatus.DR.getStatus().equals(json.getString("orderStatus"))) {
                searchable.addSort(new Sort(Direction.DESC, "CREATED"));
                // 加这个是为了显示德国效验不通过订单
                searchable.addSort(new Sort(Direction.DESC, "ADDRESS_CHECK_STATUS='N'"));
            } else {
                searchable.addSort(new Sort(Direction.DESC, "ORDER_TIME"));
            }
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable<?> searchable = buildSearchablePageParams(null);
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        Page<OutboundOrderVo> pagelist = outboundOrderService.getOrderListBySeller(command);
        if (pagelist != null) {
            List<Map<String, Object>> datalist = buildOrderList(pagelist.getContent());
            Map<String, Object> pageMap = getPageParams(pagelist);
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            data.put("pageParams", pageMap.get("pageParams"));
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    private List<Map<String, Object>> buildOrderList(List<OutboundOrderVo> datalist) {
        List<Map<String, Object>> rslist = new ArrayList<Map<String, Object>>();
        for (OutboundOrderVo order : datalist) {
            rslist.add(OutboundOrderBuilder.buildOutboundOrderListPageVo(order));
        }
        return rslist;
    }

    /**
     * 提交订单(支持批量).
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/submitOrder")
    public String submitOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        SubmitOutboundOrderCommand command = new SubmitOutboundOrderCommand();
        List<String> orderNoList = new ArrayList<String>();
        Map<String, Object> data = new HashMap<String, Object>();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            ValidateUtil.validNotNull(jsonObj, "orderNoList");
            JSONArray jsonArray = jsonObj.getJSONArray("orderNoList");
            if (null == jsonArray || jsonArray.size() == 0) {
                throw new ApiException(ErrorCode.FIELD_NOT_NULL, "orderNoList");
            }
            for (Object item : jsonArray) {
                JSONObject json = (JSONObject) item;
                ValidateUtil.validNotNull(json, "orderNo");
                ValidateUtil.validMaxLength(json, "orderNo", 64);
                orderNoList.add(json.getString("orderNo"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, data);
        }
        command.setOrderNoList(orderNoList);
        Response result = outboundOrderService.submitOrder(command);
        if (result != null) {
            data.put("resultCount", result.getResultCount());
            data.put("IsSuccess", result.getIsSuccess());
            data.put("response", result.getErrorResultList());
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 取消订单(支持批量)
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/batchVoidOrder")
    public String batchVoidOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        Map<String, Object> data = new HashMap<String, Object>();
        BatchVoidOutboundOrderCommand command = new BatchVoidOutboundOrderCommand();
        List<String> orderNoList = new ArrayList<String>();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            ValidateUtil.validNotNull(jsonObj, "orderNoList");
            JSONArray jsonArray = jsonObj.getJSONArray("orderNoList");
            if (null == jsonArray || jsonArray.size() == 0) {
                throw new ApiException(ErrorCode.FIELD_NOT_NULL, "orderNoList");
            }
            for (Object item : jsonArray) {
                JSONObject json = (JSONObject) item;
                ValidateUtil.validNotNull(json, "orderNo");
                ValidateUtil.validMaxLength(json, "orderNo", 64);
                orderNoList.add(json.getString("orderNo"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setOrderNoList(orderNoList);
        VoidResponse result = outboundOrderBatchImportService.batchVoidOrder(command);
        if (result != null) {
            data.put("successNum", result.getSuccessNum());
            data.put("failNum", result.getFailNum());
            data.put("response", result.getErrorResultList());
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 订单详情.
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryOrderByOrderNo")
    public String queryOrderByOrderNo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            ValidateUtil.validNotNull(jsonObj, "orderNo");
            ValidateUtil.validMaxLength(jsonObj, "orderNo", 64);
            OutboundOrderVo vo = new OutboundOrderVo();
            vo.setOrderNo(jsonObj.getString("orderNo"));
            command.setOrder(vo);
            command.setCtx(CommandContext.getContext());
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        OutboundOrderVo outboundOrderVo = outboundOrderService.queryOrderByOrderNo(command);
        Map<String, Object> map = new HashMap<String, Object>();
        if (null != outboundOrderVo) {
            // 构建返回参数
            map = OutboundOrderBuilder.buildReturnOutboundOrderInfo(outboundOrderVo);
            // 从GFS已发货订单，显示ebay订单商品相关信息
            GetByKeyCommand<String> getByKeyCommand = new GetByKeyCommand<String>();
            getByKeyCommand.setSearchKey(outboundOrderVo.getOrderNo());
            try {
                GfsOrder gfsOrder = gfsOrderServices.getGfsOrderByOrderNo(getByKeyCommand);
                if (gfsOrder != null) {
                    Map<String, Object> data = buildGFSOrder(gfsOrder);
                    map.put("gfsOrder", data);
                }
            } catch (Exception e) {
                logger.error("根据订单号[{}]查询GFS订单失败,错误:", outboundOrderVo.getOrderNo(), e);
            }
            //异步查询作废订单的轨迹信息
            if(EnumConstant.OrderStatus.VO.getStatus().equals(outboundOrderVo.getStatus())){
                QueryOrderTrackingCommand trackingCommand = new QueryOrderTrackingCommand();
                trackingCommand.setOrderNo(outboundOrderVo.getOrderNo());
                trackingCommand.setStatus(EnumConstant.OrderStatus.VO.getStatus());
                try {
                    OutboundOrderTrackingVo trackingVo = outboundOrderTrackingService.getOrderTrackingVo(trackingCommand);
                    if(null != trackingVo){
                        Map<String, Object> trackingData = buildTrackingVo(trackingVo);
                        map.put("trackingOrder", trackingData);
                    }
                } catch (Exception e) {
                    logger.error("根据订单号[{}]查询轨迹信息失败,错误：{}",outboundOrderVo.getOrderNo(),e);
                }
            }
        }
        responseMsg.setData(map);
        return SUCCESS;
    }

    /**
     * 根据挂号查询订单详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryOrderByTrackingNo")
    public String queryOrderByTrackingNo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        String trackingNo = null;
        String orderNo = null;
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            // build
            trackingNo = jsonObj.getString("trackingNo");
            orderNo = jsonObj.getString("orderNo");
            // validate
            if (StringUtils.isNotBlank(trackingNo)) {
                ValidateUtil.validMaxLength(jsonObj, "trackingNo", 40);
            } else if (StringUtils.isNotBlank(orderNo)) {
                ValidateUtil.validMaxLength(jsonObj, "orderNo", 128);
            }
            // 清除当前登录用户信息,给予可查看所有订单信息的权限
            CommandContext.getContext().set(ApiConstant.API_BPARTNER, null);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        QueryOrderByTrackingNoCommand command = new QueryOrderByTrackingNoCommand();
        command.setTrackingNo(trackingNo);
        command.setOrderNo(orderNo);
        command.setCtx(CommandContext.getContext());
        OutboundOrderWorkOrderHelpVo outboundOrderVo = outboundOrderService.queryOrderByTrackingNo(command);

        Map<String, Object> map = new HashMap<String, Object>();
        if (null != outboundOrderVo) {
            // 新出库单有数据
            OutboundOrderBuilder.buildReturnOutboundOrderInfoByWorkOrder(map, outboundOrderVo);
        } else {
            // 新出库单没有数据则查询erp的出库单数据
            QueryOrderByTrackingNoForWorkOrderCommand command2 = new QueryOrderByTrackingNoForWorkOrderCommand(); // 老出库单command
            command2.setTrackingNo(trackingNo);
            command2.setOrderNo(orderNo);
            OutboundOrderWorkOrderHelpVo2 erpOrderVo = outboundOrderInfoForWorkOrderService.queryOrderByTrackingNo(command2);
            if (null != erpOrderVo) {
                OutboundOrderBuilder.buildReturnOutboundOrderInfoByWorkOrder(map, erpOrderVo);
            }
        }
        responseMsg.setData(map);
        return SUCCESS;
    }
    
    @RequestMapping(value = "/batchQueryOrderByOrders")
    public String batchQueryOrderByOrders(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        BatchQueryOutboundOrderCommand command = new BatchQueryOutboundOrderCommand();
        List<String> orderNoList = new ArrayList<String>();
        List<String> trackingNoList = new ArrayList<String>();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            JSONArray orderNoArray = jsonObj.getJSONArray("orderNos");
            JSONArray trackingNoArray = jsonObj.getJSONArray("trackingNos");
            if(null != orderNoArray && orderNoArray.size() > 0){
                for(Object orderItem: orderNoArray){
                    JSONObject json = (JSONObject) orderItem;
                    ValidateUtil.validNotNull(json, "orderNo");
                    ValidateUtil.validMaxLength(json, "orderNo", 64);
                    orderNoList.add(json.getString("orderNo"));
                }
            } else if(null !=trackingNoArray && trackingNoArray.size() > 0){
                for(Object trackingItem: trackingNoArray){
                    JSONObject json = (JSONObject) trackingItem;
                    ValidateUtil.validNotNull(json, "trackingNo");
                    ValidateUtil.validMaxLength(json, "trackingNo", 64);
                    trackingNoList.add(json.getString("trackingNo"));
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_NOT_NULL,"data");
            }
            // 清除当前登录用户信息,给予可查看所有订单信息的权限
            CommandContext.getContext().set(ApiConstant.API_BPARTNER, null);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setOrderNos(orderNoList);// 订单集合
        command.setTrackingNos(trackingNoList);// 挂号集合
        command.setCtx(CommandContext.getContext()); // 上下文
        OutboundOrderWorkOrderVo workOrderVo = outboundOrderService.batchQueryOrderByOrderNoOrTrackingNo(command);
        List<Map<String,Object>> map = new ArrayList<Map<String,Object>>();
        if(null != workOrderVo){
            OutboundOrderBuilder.buildReturnOutboundOrderInfoByWorkOrder(map, workOrderVo);
        }
        responseMsg.setData(map);
        return SUCCESS;
    }

    /**
     * 修改出库单接口.
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/modifyOrder")
    public String modifyOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            OutboundOrderfieldValidator.validateModifyOutboundOrder(jsonObj);
            OutboundOrderVo vo = OutboundOrderBuilder.buildModifyVo(jsonObj);
            command.setOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        outboundOrderService.modifyOrder(command);
        return SUCCESS;
    }

    /**
     * 创建订单 至未提交状态
     * 
     * @param command
     * @return 返回出库单订单号
     */
    @RequestMapping(value = "/createOrder")
    public String createOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validCreateOutboundOrder(json);
            OutboundOrderVo vo = OutboundOrderBuilder.buildVo(json, requestMsg);
            // 构建取件时间
            String takeTime = supplementOrderVoTakeTime(vo.getProductInfo().getWinitProductCategory3(),
                vo.getDispatchWarehouseInfo().getWarehouseCode());
            vo.setTakeTime(takeTime);
            command.setOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建入库单
        String orderNo = outboundOrderService.createOrder2Drft(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("orderNo", orderNo);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 校验订单买家信息
     * 
     * @param command
     * @return 返回出库单订单号
     */
    @RequestMapping(value = "/validateOrderBuyerInfo")
    public String validateOrderBuyerInfo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        BatchValiadateOutboundOrderBuyerInfoCommand command = new BatchValiadateOutboundOrderBuyerInfoCommand();
        List<String> orderNoList = new ArrayList<String>();
        Map<String, Object> data = new HashMap<String, Object>();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            ValidateUtil.validNotNull(jsonObj, "orderNoList");
            JSONArray jsonArray = jsonObj.getJSONArray("orderNoList");
            if (null == jsonArray || jsonArray.size() == 0) {
                throw new ApiException(ErrorCode.FIELD_NOT_NULL, "orderNoList");
            }
            for (Object item : jsonArray) {
                JSONObject json = (JSONObject) item;
                ValidateUtil.validNotNull(json, "orderNo");
                ValidateUtil.validMaxLength(json, "orderNo", 64);
                orderNoList.add(json.getString("orderNo"));
            }
            if (null != orderNoList && orderNoList.size() > 200) {
                throw new ApiException(ErrorCode.VALIDATE_ORDER_NUMBER_EXCEED_ERROR, "orderNoList");
            }
            command.setOrderNoList(orderNoList);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, data);
        }
        Response result = outboundOrderService.batchValidateBuyerInfo(command);
        if (result != null) {
            data.put("resultCount", result.getResultCount());
            data.put("IsSuccess", result.getIsSuccess());
            data.put("response", result.getErrorResultList());
            data.put("failedCount", result.getFailedCount());
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 创建订单 至提交状态
     * 
     * @param command
     * @return 返回出库单订单号
     */
    @RequestMapping(value = "/createSubmittedOrder")
    public String createSubmittedOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validCreateOutboundOrder(json);
            OutboundOrderVo vo = OutboundOrderBuilder.buildVo(json, requestMsg);
            // 构建取件时间
            String takeTime = supplementOrderVoTakeTime(vo.getProductInfo().getWinitProductCategory3(),
                vo.getDispatchWarehouseInfo().getWarehouseCode());
            vo.setTakeTime(takeTime);
            command.setOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建入库单
        String orderNo = outboundOrderService.createOrder(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("orderNo", orderNo);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 补充订单信息 取件时间
     * 
     * @param vo
     * @param warehouseService
     */
    private String supplementOrderVoTakeTime(String orderType, String warehouseCode) {
        if (OrderType.SP.getType().equals(orderType)) {
            QueryAutoTaketimeCommand command = new QueryAutoTaketimeCommand();
            command.setWarehouseCode(warehouseCode);
            try {
                String takeTime = upsWarehouseService.automaticPickUp(command);
                if (StringUtils.isEmpty(takeTime)) {
                    throw new ApiException(ErrorCode.TAKE_TIME_IS_EMPTY_ERROR);
                }
                return takeTime;
            } catch (Exception e) {
                throw new ApiException(ErrorCode.TAKE_TIME_IS_EMPTY_ERROR);
            }
        }
        return null;
    }

    /**
     * 分销平台下单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createDistributionOrder")
    public String createDistributionOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validCreateOutboundOrder(json);
            OutboundOrderVo vo = OutboundOrderBuilder.buildVo(json, requestMsg);
            vo.setOrderSource(OrderSource.DP.getSource());
            vo.setSaleType(OutboundOrderEnumContants.saleType.DD.getStatus());
            command.setOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建入库单
        String orderNo = outboundOrderService.createOrder(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("orderNo", orderNo);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 第一步保存或更新
     * 
     * @param command
     * @param 返回订单号
     * @return
     */
    @RequestMapping(value = "/saveFirstStep")
    public String saveFirstStep(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validFirstStepField(json);
            OutboundOrderVo vo = OutboundOrderBuilder.buildFirstStep(json);
            command.setOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建入库单
        String orderNo = outboundOrderService.saveFirstStep(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("orderNo", orderNo);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 第二步保存或更新
     * 
     * @param command
     * @return
     */
    @RequestMapping(value = "/saveSecondStep")
    public String saveSecondStep(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validSecondStepField(json);
            OutboundOrderVo vo = OutboundOrderBuilder.buildSecondStep(json);
            command.setOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建入库单
        long merchandiseId = outboundOrderService.saveSecondStep(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("merchandiseId", merchandiseId);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 第三步保存或更新
     * 
     * @param command
     * @return
     */
    @RequestMapping(value = "/saveThirdStep")
    public String saveThirdStep(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validThirdStepField(json);
            OutboundOrderVo vo = OutboundOrderBuilder.buildThirdStep(json);
            command.setOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建出库单
        outboundOrderService.saveThirdStep(command);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 第四步保存或更新（保存到草稿）
     * 
     * @param command
     * @return
     */
    @RequestMapping(value = "/saveFouthStep")
    public String saveFouthStep(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validFouthStepField(json);
            OutboundOrderVo vo = OutboundOrderBuilder.buildFouthStep(json);
            command.setOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建入库单
        outboundOrderService.saveFouthStep(command);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 批量导入出库单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/batchImportOutbound")
    public String batchImportOutbound(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        BatchCreateOutboundOrderCommand command = new BatchCreateOutboundOrderCommand();
        List<OutboundOrderVo> list = new ArrayList<OutboundOrderVo>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            JSONArray array = json.getJSONArray("orderList");
            int i = 0;
            List<ErrorResult> errorResults = new ArrayList<ErrorResult>();
            for (Object item : array) {
                try {
                    JSONObject jsonObject = (JSONObject) item;
                    OutboundOrderfieldValidator.validImportOutboundOrder(jsonObject);
                    OutboundOrderVo vo = OutboundOrderBuilder.build(jsonObject);
                    list.add(vo);
                } catch (ApiException e) {
                    ErrorResult errorResult = new ErrorResult();
                    errorResult.setErrorCode(e.getErrorCode());
                    errorResult.setErrorIndex(i);
                    errorResult.setErrorMsg(e.getErrorMsg());
                    errorResults.add(errorResult);
                }
                i++;
            }
            if (null != errorResults && errorResults.size() > 0) {
                // 调用接口创建入库单
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("errorMsgList", errorResults);
                map.put("isSuccess", false);
                map.put("resultCount", errorResults.size());
                map.put("totalCount", array.size());
                map.put("successCount", 0);
                map.put("failedCount", array.size());
                map.put("orderNoList", null);
                responseMsg.setData(map);
                responseMsg.setMsg("SUCCESS");
                return SUCCESS;
            }
            command.setList(list);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建入库单
        Response response = outboundOrderService.batchImportOrder(command);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("errorMsgList", response.getErrorResultList());
        map.put("isSuccess", response.getIsSuccess());
        map.put("resultCount", response.getResultCount());
        map.put("totalCount", response.getTotalCount());
        map.put("successCount", response.getSuccessCount());
        map.put("failedCount", response.getFailedCount());
        map.put("orderNoList", response.getOrderNoList());
        responseMsg.setData(map);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 单步提交
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/submit")
    public String submit(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        SubmitOutboundOrderCommand command = new SubmitOutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validSubmitField(json);
            OutboundOrderVo vo = OutboundOrderBuilder.buildSubmit(json);
            command.setOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建入库单
        OrderSubmitResultVo resultVo=outboundOrderService.submit(command);
        if(resultVo!=null){
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("isSuccess", resultVo.getIsSuccess());
            map.put("orderResultList", resultVo.getOrderResultList());
            responseMsg.setData(map);
        }
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 订单再次提交
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/reOrder")
    public String reOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        ReOrderCommand command = new ReOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validMaxLength(json, "orderNo", 64);
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        String orderNo = outboundOrderService.reOrder(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("orderNo", orderNo);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    @RequestMapping(value = "/exportOrderList")
    public String exportOrderList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryOrderBySellerCommand command = new QueryOrderBySellerCommand();
        List<String> orderNoList = new ArrayList<String>();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validQueryByMainOrderParam(json);
            command = OutboundOrderBuilder.buildOutboundCommand(json);
            if (json.containsKey("orderNoList")) {
                JSONArray jsonArray = json.getJSONArray("orderNoList");
                if (null == jsonArray || json.size() == 0) {
                    throw new ApiException(ErrorCode.FIELD_NOT_NULL, "orderNoList");
                }
                for (Object item : jsonArray) {
                    JSONObject jsonObj = (JSONObject) item;
                    ValidateUtil.validNotNull(jsonObj, "orderNo");
                    ValidateUtil.validMaxLength(jsonObj, "orderNo", 64);
                    orderNoList.add(jsonObj.getString("orderNo"));
                }
                command.setOrderNoList(orderNoList);
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        List<OutboundOrderVo> orderlist = outboundOrderService.exportOrderList(command);
        if (orderlist != null && orderlist.size() > 0) {
            List<Map<String, Object>> rslist = new ArrayList<Map<String, Object>>();
            for (OutboundOrderVo order : orderlist) {
                rslist.add(OutboundOrderBuilder.buildExportOrderList(order));
            }
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", rslist);
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 导出出库单 
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/exportOrder")
    public String exportOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryOrderBySellerCommand command = new QueryOrderBySellerCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validQueryByMainOrderParam(json);
            command = OutboundOrderBuilder.buildOutboundCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        outboundOrderService.exportOutboundOrder(command);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 查询返利记录列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @SuppressWarnings("rawtypes")
    @RequestMapping(value = "/rebateOrderList")
    public String getRebateOrderList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryOrderRebateCommand command = new QueryOrderRebateCommand();
        OutboundOrderRebateVo vo = new OutboundOrderRebateVo();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validRebate(json);
            vo = OutboundOrderBuilder.rebateOrderList(json);
            Searchable searchable = buildSearchablePageParams(json);
            command.setRebateOrderVo(vo);
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchablePageParams(null);
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        Page<OutboundOrderRebateVo> pagelist = outboundOrderRebateService.getOrderRebateList(command);
        if (pagelist != null && pagelist.getContent() != null && pagelist.getContent().size() > 0) {
            List<Map<String, Object>> datalist = OutboundOrderBuilder.buildRebateOrderList(pagelist.getContent());
            Map<String, Object> pageMap = getPageParams(pagelist);
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            data.put("pageParams", pageMap.get("pageParams"));
            responseMsg.setData(data);
        }

        return SUCCESS;
    }

    /**
     * 导入返利记录
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/importRebateOrder")
    public String importRebateOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        BatchRebateOrderCommand command = new BatchRebateOrderCommand();
        Object obj = requestMsg.getData();
        List<OutboundOrderRebateVo> list = new ArrayList<OutboundOrderRebateVo>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            JSONArray array = json.getJSONArray("list");
            Map<String, Object> map=new HashMap<String, Object>();
            for (Object item : array) {
                JSONObject jsonObject = (JSONObject) item;
                String orderNo=jsonObject.getString("orderNo");
                if(map.containsKey(orderNo)){
                    throw new ApiException(ErrorCode.OUTBOUND_ORDER_REPEAT_ERROR, orderNo);
                }else{
                    map.put(orderNo, orderNo);
                }
                OutboundOrderfieldValidator.validImportRebate(jsonObject);
                OutboundOrderRebateVo vo = OutboundOrderBuilder.buildRebateOrder(jsonObject);
                list.add(vo);
            }
            command.setList(list);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        Response response = outboundOrderRebateService.batchImportRebateOrder(command);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("errorMsgList", response.getErrorResultList());
        map.put("isSuccess", response.getIsSuccess());
        map.put("resultCount", response.getResultCount());
        responseMsg.setData(map);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 导出返利记录列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/exportRebateList")
    public String exportRebateList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryOrderRebateCommand command = new QueryOrderRebateCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            OutboundOrderRebateVo vo = new OutboundOrderRebateVo();
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validRebate(json);
            vo = OutboundOrderBuilder.rebateOrderList(json);
            command.setRebateOrderVo(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        List<OutboundOrderRebateVo> pagelist = outboundOrderRebateService.exportOrderRebateList(command);
        if (pagelist != null && pagelist.size() > 0) {
            List<Map<String, Object>> datalist = OutboundOrderBuilder.buildExportRebateOrderList(pagelist);
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 校验及预估
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/validateAndEstimate")
    public String validateAndEstimate(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        BatchValidateOutboundOrderCommand command = new BatchValidateOutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validImportOutboundOrder(json);
            OutboundOrderVo vo = OutboundOrderBuilder.build(json);
            List<OutboundOrderVo> orderList = new ArrayList<OutboundOrderVo>();
            orderList.add(vo);
            command.setOrderList(orderList);
        }
        // 调用接口创建入库单
        List<OrderValidateResponse> responses = outboundOrderService.validateAndEstimate(command);
        // 目前只支持单个校验预估
        OrderValidateResponse response = responses.get(0);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("errorMsgList", response.getErrorResultList());
        map.put("isSuccess", response.getIsSuccess());
        map.put("order", response.getOrderVO());
        responseMsg.setData(map);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 单个更新草稿订单
     * 
     * @param command
     * @return 返回出库单订单号
     */
    @RequestMapping(value = "/updateDraftOrder")
    public String updateDraftOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OutboundOrderCommand command = new OutboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            OutboundOrderfieldValidator.validUpdateDraftOrder(json);
            command.setOrder(OutboundOrderBuilder.buildUpdateDraftOrderVo(json));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        outboundOrderService.updateDraftOrder(command);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 更新草稿订单(支持批量)
     * 
     * @param command
     * @return
     */
    @RequestMapping(value = "/batchUpdateDraftOrder")
    public String batchUpdateDraftOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        BatchCreateOutboundOrderCommand command = new BatchCreateOutboundOrderCommand();
        List<OutboundOrderVo> list = new ArrayList<OutboundOrderVo>();
        Integer totalCount = 0;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            JSONArray array = json.getJSONArray("orderList");
            totalCount = array.size();
            int i = 0;
            List<ErrorResult> errorResults = new ArrayList<ErrorResult>();
            for (Object item : array) {
                try {
                    JSONObject jsonObject = (JSONObject) item;
                    OutboundOrderfieldValidator.validUpdateOutboundOrder(jsonObject);
                    OutboundOrderVo vo = OutboundOrderBuilder.build(jsonObject);
                    list.add(vo);
                } catch (ApiException e) {
                    ErrorResult errorResult = new ErrorResult();
                    errorResult.setErrorCode(e.getErrorCode());
                    errorResult.setErrorIndex(i);
                    errorResult.setErrorMsg(e.getErrorMsg());
                    errorResults.add(errorResult);
                }
                i++;
            }
            if (null != errorResults && errorResults.size() > 0) {
                // 调用接口创建入库单
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("errorMsgList", errorResults);
                map.put("isSuccess", false);
                map.put("resultCount", errorResults.size());
                map.put("orderNoList", null);
                map.put("totalCount", totalCount);
                map.put("successCount", totalCount - errorResults.size());
                map.put("failedCount", errorResults.size());
                responseMsg.setData(map);
                responseMsg.setMsg("SUCCESS");
                return SUCCESS;
            }
            command.setList(list);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建入库单
        Response response = outboundOrderService.batchUpdateDraftOrder(command);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("errorMsgList", response.getErrorResultList());
        map.put("isSuccess", response.getIsSuccess());
        map.put("orderNoList", response.getOrderNoList());
        map.put("resultCount", response.getResultCount());
        map.put("totalCount", response.getTotalCount());
        map.put("successCount", response.getSuccessCount());
        map.put("failedCount", response.getFailedCount());
        responseMsg.setData(map);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    @RequestMapping(value = "/queryOrderPerformance")
    public String queryOrderPerformance(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        OutBoundOrderHistoricalPerformanceCommand command = new OutBoundOrderHistoricalPerformanceCommand();
        Object obj = requestMsg.getData();
        String customerCode = null;
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            customerCode = jsonObj.getString("customerCode");
            // validate
            if (StringUtils.isNotBlank(customerCode)) {
                ValidateUtil.validMaxLength(jsonObj, "customerCode",128);
                command.setCustomerCode(customerCode);
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口查詢订单时效
        List<OutboundOrderHistoricalPerformanceVo> list = outboundOrderTimelyAndQuantityService.queryHistoricalPerformance(command);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("dataList", list);
        responseMsg.setData(map);
        return SUCCESS;
    }
    
    @RequestMapping(value = "/queryOrderPerformanceList")
    public String queryOrderPerformanceList(@ModelAttribute RequestMsg requestMsg,
                                            @ModelAttribute ResponseMsg responseMsg) {
        OutBoundOrderHistoricalPerformanceCommand command = new OutBoundOrderHistoricalPerformanceCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
            if (null == bpartner) {
                throw new ApiException(ErrorCode.BPARTNER_NOT_FOUND_ERROR);
            } 
            command.setCustomerCode(bpartner.getValue());
            if (jsonObj.containsKey("warehouseCode")) {
                command.setWarehouseCode(jsonObj.getString("warehouseCode"));
            }
            if (jsonObj.containsKey("winitProductCode")) {
                command.setWinitProductCode(jsonObj.getString("winitProductCode"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口查詢订单时效
        List<OutboundOrderPerformanceReponseVo> list = outboundOrderTimelyAndQuantityService.queryHistoricalPerformanceList(command);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("list", list);
        responseMsg.setData(map);
        return SUCCESS;
    }

    @RequestMapping(value = "/queryOrderQuantity")
    public String queryOrderQuantity(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        OutBoundOrderQuantityCommand command = new OutBoundOrderQuantityCommand();
        Object obj = requestMsg.getData();
        String customerCode = null;
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            customerCode = jsonObj.getString("customerCode");
            // validate
            if (StringUtils.isNotBlank(customerCode)) {
                ValidateUtil.validMaxLength(jsonObj, "customerCode",128);
                command.setCustomerCode(customerCode);
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口查询订单数量
        List<OutboundOrderQuantityVo> list = outboundOrderTimelyAndQuantityService.queryQuantity(command);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("dataList", list);
        responseMsg.setData(map);
        return SUCCESS;
    }
    
    
    @RequestMapping(value = "/queryWarehouseList")
    public String queryWarehouseList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        OutBoundOrderHistoricalPerformanceCommand command = new OutBoundOrderHistoricalPerformanceCommand();
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (null == bpartner) {
            throw new ApiException(ErrorCode.BPARTNER_NOT_FOUND_ERROR);
        } 
        command.setCustomerCode(bpartner.getValue());
        // 调用接口查詢订单时效
        List<Map<String, String>> list = outboundOrderTimelyAndQuantityService.queryWarehouseList(command);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("warehouseList", list);
        responseMsg.setData(map);
        return SUCCESS;
    }
    
    @RequestMapping(value = "/queryPscList")
    public String queryPscList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        OutBoundOrderHistoricalPerformanceCommand command = new OutBoundOrderHistoricalPerformanceCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            // validate
            ValidateUtil.validNotNull(jsonObj, "warehouseCode");
            if (jsonObj.containsKey("warehouseCode")) {// 仓库编码
                ValidateUtil.validMaxLength(jsonObj, "warehouseCode", 128);
            }
            Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
            if (null == bpartner) {
                throw new ApiException(ErrorCode.BPARTNER_NOT_FOUND_ERROR);
            } 
            command.setCustomerCode(bpartner.getValue());
            command.setWarehouseCode(jsonObj.getString("warehouseCode"));
            command.setWinitProductCategory3(PmsConstants.PRODUCT_CATEGORY_OSF81);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口查詢订单时效
        List<Map<String, String>> list = outboundOrderTimelyAndQuantityService.queryPscList(command);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("pscList", list);
        responseMsg.setData(map);
        return SUCCESS;
    }
    
    
    @RequestMapping(value = "/queryOrderForStandardClaim")
    public String queryOrderForStandardClaim(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
        Object obj = requestMsg.getData();
        List<String> documentNoList = new ArrayList<String>();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            // build
            JSONArray documentNos = jsonObj.getJSONArray("documentNos");
            // validate
            for(Object item : documentNos){
                JSONObject jsonObject = (JSONObject) item;
                ValidateUtil.validNotNull(jsonObject, "documentNo");
                ValidateUtil.validMaxLength(jsonObject, "documentNo", 128);
                documentNoList.add(jsonObject.getString("documentNo").trim());
            }
            // 清除当前登录用户信息,给予可查看所有订单信息的权限
            CommandContext.getContext().set(ApiConstant.API_BPARTNER, null);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        QueryOrderByTrackingNoCommand command = new QueryOrderByTrackingNoCommand();
        command.setDocumentNos(documentNoList);
        command.setCtx(CommandContext.getContext());
        OutboundOrderWorkOrderVo outboundOrderVo = outboundOrderService.queryOrderForStandardClaim(command);
        List<Map<String,Object>> map = new ArrayList<Map<String,Object>>();
        if (null != outboundOrderVo) {
            // 组装返回数据
            OutboundOrderBuilder.buildReturnOutboundOrderInfoByWorkOrder(map, outboundOrderVo);
        }
        responseMsg.setData(map);
        return SUCCESS;
    }

    private Map<String, Object> buildGFSOrder(GfsOrder gfs) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("gfsOrderId", gfs.getOrderId());
        data.put("status", gfs.getStatus());
        data.put("warehouseID", gfs.getWinitwarehouseID());
        data.put("winitOrderCode", gfs.getWinitOrderCode());
        data.put("warehouseCode", gfs.getWarehouseCode());
        data.put("warehouseName", gfs.getWarehouseName());
        data.put("deliveryWay", gfs.getDeliveryWayCode());
        data.put("deliveryWayName", gfs.getDeliveryWayName());
        data.put("insuranceType", gfs.getInsuranceType());
        data.put("buyerUserId", gfs.getBuyerUserId());// 买家ID
        data.put("sellerUserId", gfs.getSellerUserId());// 卖家ID
        data.put("sellerOrderCode", gfs.getSellerOrderCode());// 客户订单号
        data.put("buyerFullname", gfs.getBuyerFullname());
        data.put("buyerEmail", gfs.getBuyerEmail());
        data.put("buyerPhone", gfs.getBuyerPhone());
        data.put("buyerCountry", gfs.getBuyerCountry());
        data.put("buyerState", gfs.getBuyerState());
        data.put("buyerCity", gfs.getBuyerCity());
        data.put("buyerPostCode", gfs.getBuyerPostCode());
        data.put("buyerAddreess", gfs.getBuyerAddreess2());
        data.put("buyerAddreess2", gfs.getBuyerAddreess3());
        data.put("checkOutDate", gfs.getCheckOutDate());
        data.put("paymentDate", gfs.getPaymentDate());// 付款时间
        data.put("postageDate", gfs.getPostageDate());
        data.put("feedbackSent", gfs.getFeedbackSent());
        data.put("feedbackReceive", gfs.getFeedbackReceive());
        data.put("paymentMethod", gfs.getPaymentMethod());
        data.put("postedDate", gfs.getPostedDate());
        data.put("postageService", gfs.getPostageService());// 原始派送方式
        data.put("lastEmailSent", gfs.getDeliveryDate());// 发货时间
        data.put("saleDate", gfs.getSaleDate());
        data.put("errorMsg", gfs.getErrorMsg());
        data.put("ebayProductList", gfs.getEbayProductList());
        data.put("productList", gfs.getProductList());
        data.put("ebayTransactionType", gfs.getEbayTransactionType());
        data.put("orderType", gfs.getOrderType());
        data.put("shipperAddrCode", gfs.getShipperAddrCode());
        data.put("winitProductCode", gfs.getWinitProductCode());
        data.put("winitProductName", gfs.getWinitProductName());
        data.put("extent", gfs.getExtent());
        data.put("weight", gfs.getWeight());
        data.put("width", gfs.getWidth());
        data.put("height", gfs.getHeight());
        data.put("doorplateNumbers", gfs.getDoorpLateNumbers());
        data.put("trackingNo", gfs.getTrackingNo());
        data.put("totalAllPrice", gfs.getTotalAllPrice());
        data.put("totalPriceCurrency", gfs.getTotalPriceCurrency());
        data.put("txStoreKey",gfs.getTxStoreKey());// 平台对应的key
        data.put("txVSAccountID",gfs.getTxVSAccountID());// Teapplix的虚拟账户id
        data.put("txShipping",gfs.getTxShipping());// 运费
        data.put("txTax",gfs.getTxTax());// 税
        data.put("txHandling",gfs.getTxHandling());// 处理费
        data.put("txDiscount",gfs.getTxDiscount());// 优惠
        data.put("txInsuranceType",gfs.getTxInsuranceType());// 保险类型
        data.put("txCurrency",gfs.getTxCurrency()); // 币种
        data.put("txMemo",gfs.getTxMemo());// 备注
        data.put("txGiftMessage",gfs.getTxGiftMessage());// 包装信息
        data.put("platform",gfs.getPlatform());// 订单来源
        data.put("txStoreKey", gfs.getTxStoreKey());//店面账号
        //组装平台商品信息
        List<Map<String, Object>> platFormInfo = new ArrayList<Map<String,Object>>();
        Map<String, Object> platFormInfoData = new HashMap<String, Object>();
        List<GfsOrderDetail> detailList = gfs.getListGfsOrderDetail();
        if(CollectionUtils.isNotEmpty(detailList)){
            for(GfsOrderDetail detail : detailList){
                platFormInfoData.put("itemName", detail.getItemName());//平台商品名称
                platFormInfoData.put("itemId", detail.getItemId());//平台商品ID
                platFormInfoData.put("quantity", detail.getQuantity());//数量
                platFormInfoData.put("transactionPrice", detail.getTransactionPrice());//商品总价值
                platFormInfoData.put("itemDescription", detail.getItemDescription());//商品描述
                platFormInfo.add(platFormInfoData);
            }
        }
        data.put("platFormInfo", platFormInfo);
        return data;
    }
    
    private Map<String,Object> buildTrackingVo(OrderTracking orderTracking){
        Map<String, Object> map = new HashMap<String, Object>();
        if(null == orderTracking){
            return map;
        }
        map.put("orderNo", orderTracking.getOrderNo());
        map.put("trackingCode",orderTracking.getTrackingCode());
        map.put("operator", orderTracking.getOperator());
        map.put("mark", orderTracking.getMark());
        map.put("isOperateByWinit", orderTracking.getIsOperateByWinit());
        return map;
    }
    
}
